module zl_2346_7_1(cp,rst_n,key_in,FTW,freq,addr);
//输入与输出
input cp;				//100kHz
input rst_n;			//复位
input key_in;			//输入键
output [23:0]FTW;		//FTW频率控制字
output [23:0]freq;	//更改后的频率输出
output [6:0] addr;	//rom地址

//计数器的相关参数
localparam t_1s = 25'd99_999;
localparam t_100ms = 25'd9_999;
localparam t_3s = 2'd3;
reg count_en;  //判断是否为长按
reg count2_en; //判断长按时的计数

reg [23:0] FTW;
reg [23:0] freq;
reg [6:0]  addr;
reg [1:0]  state; //用于状态机表状态
reg [23:0] m;		//相位累加器
reg [27:0] count;
reg [1:0]  count1;
reg [27:0] count2;
reg [2:0] key_in_reg; //按键状态，上升沿/下降沿

wire key_in_pos;		//输入是否为上升沿
wire key_in_neg;		//输入是否为下降沿

//边沿检测模块
always @(posedge cp or negedge rst_n) begin
	if(!rst_n) begin
		key_in_reg <= 3'b000;
	end
	else begin
		key_in_reg <= {key_in_reg[1:0],key_in};
	end
end

assign key_in_pos = {key_in_reg[2:1] == 2'b01};
assign key_in_neg = {key_in_reg[2:1] == 2'b10};

//1s计数器
always @(posedge cp or negedge rst_n) begin
	if(!rst_n) begin
		count <=28'b0;
	end
	else if(count_en) begin
		if(count == t_1s)
			count <= 1'b0;
		else
			count <= count +1'b1;
	end
	else
		count <= 28'b0;
end

//3s计数器
always @(posedge cp or negedge rst_n) begin
	if(!rst_n) begin
		count1 <= 1'b0;
	end
	else if (count_en) begin
		if(count1 == t_3s)
			count1 <= t_3s;
		else if(count == t_1s)
			count1 <= count1 + 1'b1;
	end
	else
		count1 <= 1'b0;
end

//100ms计数器
always @(posedge cp or negedge rst_n) begin
	if(!rst_n) begin
		count2 <= 28'b0;
	end
	else if(count2_en) begin
		if(count2 == t_100ms)
			count2 <= 28'b0;
		else
			count2 <= count2 + 1'b1;
	end
	else
		count2 <= 28'b0;
end

//状态机
always @(posedge cp or negedge rst_n) begin
	if(!rst_n) begin			//复位清零
		state 		<= 2'd0;
		count_en 	<= 1'd0;
		count2_en 	<= 1'd0;
		FTW 			<= 1'd0;
		freq 			<= 1'd0;
		m 				<= 1'd0;
		addr 			<= 1'd0;
	end
	else begin
	case(state)
		2'd0: begin				//未按下的状态，释放状态
			count_en 	<= 1'd0;
			count2_en 	<= 1'd0;
			if(key_in_pos)		//按键按下，进入按下状态1
				state <= 2'd1;
			else
				state <= 2'd0;
		end
		2'd1: begin				
			if(key_in_neg) begin	//短按
				count_en 	<= 1'b0;
				count2_en 	<= 1'b0;
				state <= 2'd0;
				FTW <= FTW + 10'd168;	//频率控制字增加336，频率步进1
			end
			else if((key_in_reg == 3'b111) && (count1 == t_3s)) begin
				count_en  <= 1'b0;
				count2_en <= 1'b1;
				state <= 2'd2;
			end
			else
				count_en <= 1'b1;
		end
		2'd2: begin					//长按
			if(key_in_neg) begin
				state <= 2'd0;
				count2_en <= 1'b0;
			end
			else if((key_in_reg == 3'b111) && (count2 == t_100ms)) begin
				state <= 2'd2;
				FTW <= FTW + 12'd1_680;	//频率控制字增加10*168，频率步进10
			end
			else
				count2_en <= 1'b1;
		end
		default : state <= 2'd0;
	endcase
	m = m + FTW;							//将FTW累加至相位累加器
	freq <= 5960 * FTW / 1000000;		//计算频率
	addr <= m[23:17];						//由MSB输出地址
	end
end

endmodule
